/*
 * InputForm.java
 *
 * Created on 13-Aug-2009, 14:44:25
 * Copyright me
 */
package iffmyexp;

import com.icesoft.faces.async.render.SessionRenderer;
import com.icesoft.faces.component.ext.HtmlDataTable;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlInputTextarea;
import com.icesoft.faces.component.ext.HtmlOutputText;
import com.icesoft.faces.component.ext.HtmlPanelGrid;
import com.icesoft.faces.component.ext.HtmlSelectManyCheckbox;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.ext.HtmlSelectOneRadio;
import com.icesoft.faces.component.inputfile.InputFile;
import com.sun.rave.web.ui.appbase.AbstractPageBean;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import javax.faces.FacesException;
import javax.faces.component.UIInput;
import javax.faces.component.UISelectItem;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import tavernacon.DataResource;
import tavernacon.DataValue;
import tavernacon.RESTClient;

/**
 * <p>Page bean that corresponds to a similarly named JSP page.  This
 * class contains component definitions (and initialization code) for
 * all components that you have defined on this page, as well as
 * lifecycle methods and event handlers where you may add behavior
 * to respond to incoming events.</p>
 */
public class InputForm extends AbstractPageBean {

    static Vector inputsVector;
    static String[] filesInDir;

    // <editor-fold defaultstate="collapsed" desc="Managed Component Definition">
    private int __placeholder;

    /**
     * <p>Automatically managed component initialization.  <strong>WARNING:</strong>
     * This method is automatically generated, so any user-specified code inserted
     * here is subject to being replaced.</p>
     */
    private void _init() throws Exception {
    }
    private HtmlInputTextarea inputTextarea1 = new HtmlInputTextarea();

    public HtmlInputTextarea getInputTextarea1() {
        return inputTextarea1;
    }

    public void setInputTextarea1(HtmlInputTextarea hit) {
        this.inputTextarea1 = hit;
    }
    private String t = "false";

    public String gett() {
        return "falsfgdfg";
    }

    public void t(String hit) {
        this.t = "false";
    }
    public static HtmlDataTable workflowsTable = new HtmlDataTable();

    public HtmlDataTable getWorkflowsTable() {
        return workflowsTable;
    }

    public void setWorkflowsTable(HtmlDataTable hdt) {
        this.workflowsTable = hdt;
    }
    public static HtmlDataTable inputsTable = new HtmlDataTable();

    public HtmlDataTable getInputsTable() {
        return inputsTable;
    }
    public HtmlOutputText workflowName = new HtmlOutputText();

    public HtmlOutputText getWorkflowName() {
        return workflowName;
    }

    public void setWorkflowName(HtmlOutputText hot) {
        this.workflowName = hot;
    }
    public HtmlOutputText workflowDesc = new HtmlOutputText();

    public HtmlOutputText getWorkflowDesc() {
        return workflowDesc;
    }

    public void setWorkflowDesc(HtmlOutputText hot) {
        this.workflowDesc = hot;
    }
    private HtmlPanelGrid containerComponent;

    public HtmlPanelGrid getContainerComponent() {
        return containerComponent;
    }

    public void setContainerComponent(HtmlPanelGrid containerComponent) {
        this.containerComponent = containerComponent;
    }
    private HtmlPanelGrid containerErrors;

    public HtmlPanelGrid getContainerErrors() {
        return containerErrors;
    }

    public void setContainerErrors(HtmlPanelGrid containerComponent) {
        this.containerErrors = containerComponent;
    }

    public void setinputsTable(HtmlDataTable hdt) {
        this.inputsTable = hdt;
    }
    public HtmlPanelGrid pg = new HtmlPanelGrid();
    public boolean workflowsVis = false;

    public boolean getWorkflowsVis() {
        return workflowsVis;
    }

    public void setWorkflowsVis(boolean wfb) {
        this.workflowsVis = wfb;
    }
    public boolean inputsVis = false;

    public boolean getInputsVis() {
        return inputsVis;
    }

    public void setInputsVis(boolean wfb) {
        this.inputsVis = wfb;
    }
    public static String jobIDString = new String("");

    public String getjobIDString() {
        return jobIDString;
    }

    public void setjobIDString(String str) {
        this.jobIDString = str;
    }


    // </editor-fold>
    /**
     * <p>Construct a new Page bean instance.</p>
     */
    public InputForm() {
        SessionRenderer.addCurrentSession("changeInterface");
    }

    /**
     * <p>Callback method that is called whenever a page is navigated to,
     * either directly via a URL, or indirectly via page navigation.
     * Customize this method to acquire resources that will be needed
     * for event handlers and lifecycle methods, whether or not this
     * page is performing post back processing.</p>
     * 
     * <p>Note that, if the current request is a postback, the property
     * values of the components do <strong>not</strong> represent any
     * values submitted with this request.  Instead, they represent the
     * property values that were saved for this view when it was rendered.</p>
     */
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here

        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("MyExperimentSearch Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e : new FacesException(e);
        }

        // </editor-fold>
        // Perform application initialization that must complete
        // *after* managed components are initialized
        // TODO - add your own initialization code here
    }

    /**
     * <p>Callback method that is called after the component tree has been
     * restored, but before any event processing takes place.  This method
     * will <strong>only</strong> be called on a postback request that
     * is processing a form submit.  Customize this method to allocate
     * resources that will be required in your event handlers.</p>
     */
    public void preprocess() {
    }

    /**
     * <p>Callback method that is called just before rendering takes place.
     * This method will <strong>only</strong> be called for the page that
     * will actually be rendered (and not, for example, on a page that
     * handled a postback and then navigated to a different page).  Customize
     * this method to allocate resources that will be required for rendering
     * this page.</p>
     */
    public void prerender() {
    }

    /**
     * <p>Callback method that is called after rendering is completed for
     * this request, if <code>init()</code> was called (regardless of whether
     * or not this was the page that was actually rendered).  Customize this
     * method to release resources acquired in the <code>init()</code>,
     * <code>preprocess()</code>, or <code>prerender()</code> methods (or
     * acquired during execution of an event handler).</p>
     */
    public void destroy() {
    }

    public String showWorkflows() throws Exception {

        System.out.println("testing");

        // create a file that is really a directory
        File aDirectory = new File("wf_data");

        // get a listing of all files in the directory
        filesInDir = aDirectory.list();

        // sort the list of files (optional)
        // Arrays.sort(filesInDir);

        // have everything i need, just print it now
        for (int i = 0; i < filesInDir.length; i++) {
            System.out.println("file: " + filesInDir[i].substring(0, filesInDir[i].lastIndexOf('.')));
            filesInDir[i] = filesInDir[i].substring(0, filesInDir[i].lastIndexOf('.'));
        }



        System.out.println("Add");

        workflowsVis = true;

        workflowsTable.setValue(filesInDir);

        return null;
    }

    public String showInterface() throws Exception {


        containerComponent.getChildren().clear();
        // containerErrors.getChildren().clear();

        inputsVector = new Vector();
        String workflow = filesInDir[workflowsTable.getRowIndex()];
        inputsVis = true;

        workflowName.setValue(workflow);
        workflowDesc.setValue("hello");

        DocumentBuilderFactory Factory = DocumentBuilderFactory.newInstance();
        Factory.setNamespaceAware(true);
        DocumentBuilder builder = Factory.newDocumentBuilder();
        Document doc = builder.parse("wf_data/" + workflow + ".xml");
        //creating an XPathFactory:
        XPathFactory factory = XPathFactory.newInstance();
        //using this factory to create an XPath object:
        XPath xpath = factory.newXPath();

        XPathExpression descExpr = xpath.compile("/workflow/description/text()");
        Object descResult = descExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList descNodeList = (NodeList) descResult;

        if (descNodeList.getLength() > 0) {
            workflowDesc.setValue(descNodeList.item(0).getNodeValue());
            
        } else {
            workflowDesc.setValue("No description available");

            //XPath object created compiles the XPath expression for inputs:
            
        }
        XPathExpression typeExpr = xpath.compile("//inputs/input/type/text()");
        Object typeResult = typeExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList typeNodeList = (NodeList) typeResult;

        XPathExpression nameExpr = xpath.compile("//inputs/input/name/text()");
        Object nameResult = nameExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList nameNodeList = (NodeList) nameResult;

        XPathExpression exampleExpr = xpath.compile("//inputs/input/example/text()");
        Object exampleResult = exampleExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList exampleNodeList = (NodeList) exampleResult;

        XPathExpression descriptionExpr = xpath.compile("//inputs/input/description/text()");
        Object descriptionResult = descriptionExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList descriptionNodeList = (NodeList) descriptionResult;

        /*XPathExpression minExpr = xpath.compile("//inputs/input/restriction/min/text()");
        Object minResult = minExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList minNodeList = (NodeList) minResult;

        XPathExpression maxExpr = xpath.compile("//inputs/input/restriction/max/text()");
        Object maxResult = maxExpr.evaluate(doc, XPathConstants.NODESET);
        NodeList maxNodeList = (NodeList) maxResult;

        InputValidator.setMin(minNodeList.item(0).getNodeValue());
        InputValidator.setMax(maxNodeList.item(0).getNodeValue());*/

        //looping through the xml interface doc
        inputModel[] inputsList = new inputModel[typeNodeList.getLength()];


        for (int i = 0; i < typeNodeList.getLength(); i++) {

            Vector values = new Vector();
            //check flags by looking at UI component type



            if (typeNodeList.item(i).getNodeValue().equals("inputtext")) {
            }

            if (typeNodeList.item(i).getNodeValue().equals("textarea")) {
            }

            if (typeNodeList.item(i).getNodeValue().equals("dropdown")) {

                XPathExpression valuesExpr = xpath.compile("//inputs/input[" + (i + 1) + "]/values/value/text()");
                Object valuesResult = valuesExpr.evaluate(doc, XPathConstants.NODESET);
                NodeList valuesNodeList = (NodeList) valuesResult;

                for (int j = 0; j < valuesNodeList.getLength(); j++) {

                    UISelectItem option = new UISelectItem();
                    option.setItemValue(valuesNodeList.item(j).getNodeValue());
                    option.setItemLabel(valuesNodeList.item(j).getNodeValue());
                    values.add(option);
                }
            }

            if (typeNodeList.item(i).getNodeValue().equals("radio")) {

                XPathExpression valuesExpr = xpath.compile("//inputs/input[" + (i + 1) + "]/values/value/text()");
                Object valuesResult = valuesExpr.evaluate(doc, XPathConstants.NODESET);
                NodeList valuesNodeList = (NodeList) valuesResult;

                for (int j = 0; j < valuesNodeList.getLength(); j++) {

                    UISelectItem option = new UISelectItem();
                    option.setItemValue(valuesNodeList.item(j).getNodeValue());
                    option.setItemLabel(valuesNodeList.item(j).getNodeValue());
                    values.add(option);
                }
            }

            if (typeNodeList.item(i).getNodeValue().equals("checkbox")) {

                XPathExpression valuesExpr = xpath.compile("//inputs/input[" + (i + 1) + "]/values/value/text()");
                Object valuesResult = valuesExpr.evaluate(doc, XPathConstants.NODESET);
                NodeList valuesNodeList = (NodeList) valuesResult;

                for (int j = 0; j < valuesNodeList.getLength(); j++) {

                    UISelectItem option = new UISelectItem();
                    option.setItemValue(valuesNodeList.item(j).getNodeValue());
                    option.setItemLabel(valuesNodeList.item(j).getNodeValue());
                    values.add(option);
                }
            }

            if (typeNodeList.item(i).getNodeValue().equals("file")) {
            }

            inputModel input = new inputModel(nameNodeList.item(i).getNodeValue(), typeNodeList.item(i).getNodeValue(),
                    values, "", "", "", "", exampleNodeList.item(i).getNodeValue(), descriptionNodeList.item(i).getNodeValue(), "", "", true);

            //dynamically user interface components and putting them on the page
            HtmlOutputText inputName = new HtmlOutputText();
            inputName.setValue(input.name);//filesInDir[i]);
            inputName.setStyle("font-weight:bold; font-size:11px;");

            HtmlOutputText blank = new HtmlOutputText();
            blank.setValue(" ");//filesInDir[i]);
            blank.setStyle("font-weight:bold; font-size:12px;");

            HtmlOutputText blank2 = new HtmlOutputText();
            blank2.setValue(" ");//filesInDir[i]);
            blank2.setStyle("font-weight:bold;");
            HtmlOutputText blank3 = new HtmlOutputText();
            blank3.setValue(" ");//filesInDir[i]);
            blank3.setStyle("font-weight:bold;");
            HtmlOutputText blank4 = new HtmlOutputText();
            blank4.setValue(" ");//filesInDir[i]);
            blank4.setStyle("font-weight:bold;");
            HtmlOutputText blank5 = new HtmlOutputText();
            blank5.setValue(" ");//filesInDir[i]);
            blank5.setStyle("font-weight:bold;");

            HtmlOutputText description = new HtmlOutputText();
            description.setValue("description");//filesInDir[i]);
            description.setStyle("color:#666666;");

            HtmlOutputText inputDescription = new HtmlOutputText();
            inputDescription.setValue(input.description);//filesInDir[i]);
            inputDescription.setStyle("font-style:italic; color:#666666");

            HtmlOutputText example = new HtmlOutputText();
            example.setValue("example input");//filesInDir[i]);
            example.setStyle("color:#666666;");

            HtmlOutputText inputExample = new HtmlOutputText();
            inputExample.setValue(input.example);//filesInDir[i]);
            inputExample.setStyle("font-style:italic; color:#666666");


            // HtmlOutputText inputDescription = new HtmlOutputText();
            // inputDescription.setValue(input.example);
            // col.getChildren().add(inputDescription);

            if (containerComponent == null) {
                containerComponent = new HtmlPanelGrid();
                containerComponent.setColumns(2);
            }
            containerComponent.setColumns(2);

            /* if (containerErrors == null) {
            containerErrors = new HtmlPanelGrid();
            containerErrors.setColumns(1);
            }
            containerErrors.setColumns(1);*/

            containerComponent.getChildren().add(inputName);

            if (input.UIComponent.equals("inputtext")) {

                HtmlInputText it = new HtmlInputText();
                //it.setPartialSubmit(true);
                /*InputValidator ev = new InputValidator();
                it.addValidator(ev);
                it.setId(input.name);
                HtmlMessage hm = new HtmlMessage();
                hm.setFor(input.name);*/
                containerComponent.getChildren().add(it);
                //containerComponent.getChildren().add(hm);
            }

            if (input.UIComponent.equals("textarea")) {

                HtmlInputTextarea ita = new HtmlInputTextarea();
                containerComponent.getChildren().add(ita);
            }

            if (input.UIComponent.equals("dropdown")) {

                HtmlSelectOneMenu som = new HtmlSelectOneMenu();
                som.getChildren().addAll(values);
                containerComponent.getChildren().add(som);
            }

            if (input.UIComponent.equals("radio")) {

                HtmlSelectOneRadio sor = new HtmlSelectOneRadio();
                sor.getChildren().addAll(values);
                containerComponent.getChildren().add(sor);
            }

            if (input.UIComponent.equals("checkbox")) {
                HtmlSelectManyCheckbox smc = new HtmlSelectManyCheckbox();
                smc.getChildren().addAll(values);
                containerComponent.getChildren().add(smc);
            }

            if (input.UIComponent.equals("file")) {
                InputFile file = new InputFile();
                containerComponent.getChildren().add(file);
            }

            containerComponent.getChildren().add(description);
            containerComponent.getChildren().add(inputDescription);
            //containerComponent.getChildren().add(blank);
            containerComponent.getChildren().add(example);
            containerComponent.getChildren().add(inputExample);
            containerComponent.getChildren().add(blank2);
            containerComponent.getChildren().add(blank3);

            //containerComponent.getChildren().add(blank4);
            //containerComponent.getChildren().add(blank5);

            SessionRenderer.render("changeInterface");

            inputsList[i] = input;

        }
        //inputsTable.setValue(inputsList);
        return null;
    }

    public String runWorkflow() {

        long wfid = 0;

        try {
            DocumentBuilderFactory Factory = DocumentBuilderFactory.newInstance();
            Factory.setNamespaceAware(true);
            DocumentBuilder builder = Factory.newDocumentBuilder();
            Document doc = builder.parse("wf_data/" + workflowName.getValue() + ".xml");
            //creating an XPathFactory:
            XPathFactory factory = XPathFactory.newInstance();
            //using this factory to create an XPath object:
            XPath xpath = factory.newXPath();
            //XPath object created compiles the XPath expression for inputs:
            XPathExpression idExpr = xpath.compile("//idonserver/text()");
            Object idResult = idExpr.evaluate(doc, XPathConstants.NODESET);
            NodeList idNodeList = (NodeList) idResult;

            wfid = Long.parseLong(idNodeList.item(0).getNodeValue());
            System.out.println(wfid);
        } catch (Exception e) {
            System.out.println(e);
        }

        try {
            RESTClient tavernaRESTClient = new RESTClient();
            tavernaRESTClient.setBaseURL("http://localhost:9090/taverna-server-0.2.1/rest");



            Map<String, DataValue> ds = new HashMap<String, DataValue>();

            int noOfUIComponents = containerComponent.getChildren().size();

            System.out.println("UICs: " + noOfUIComponents);

            for (int i = 0; i < noOfUIComponents; i = i + 8) {
                HtmlOutputText name = (HtmlOutputText) containerComponent.getChildren().get(i);//.getChildren().get(0);
                UIInput in = (UIInput) containerComponent.getChildren().get(i + 1);//.getChildren().get(1);
                //Object obj = containerComponent.getChildren().get(i);
                //HtmlInputText hit = (HtmlInputText) obj;
                ds.put((String) name.getValue(), new DataValue((String) in.getValue()));

                String str = (String) name.getValue() + ", " + (String) in.getValue();
                System.out.println(str);
            }

            System.out.println("..");

            Long inputID = tavernaRESTClient.addData(new DataResource(ds));
            System.out.println("DataId :" + inputID);


            /*String workflowXML = IOUtils.toString(getClass().getResource("../test/pipeline.t2flow").openStream());
            Long workflowID = tavernaRESTClient.addWorkflow(workflowXML);
            System.out.println("WorkflowId :"+ workflowID);*/

            //Long.parseLong(idNodeList.item(0).getNodeValue());
            long startTime = System.currentTimeMillis();
            long duration = 0;
            Long jobID = tavernaRESTClient.addJob(wfid, inputID);

            jobIDString = "Job submitted. Job ID: " + jobID;
            System.out.println("JobId :" + jobID);

        } catch (Exception e) {
        }
        return null;
    }
}

